<?php


abstract class UserAvatar {
    public static  $allowedExtensions = array("jpg", "png", "gif");
    public static  $max_img_dim = 150;
    
    /*
     * APP_FILES_AVA_PATH - путь к авам из скриптов
     * APP_HTML_AVA_PATH - путь к авам из HTML
     * DEF_AVA - дефолтная аватарка
     */
    
    
    /**
     * Извлечение имени картинки из её URL
     * @param string $photoUrl
     * @return string
     */
    private static function getFileNameFromUrl($photoUrl) {
        $parts = explode('/', $photoUrl);
        if (!count($parts)) return DEF_AVA;
        
        $last = $parts[count($parts)-1];
        $parts = explode('?', $last);
        return $parts[0];
    }
    
    private static function avaFileName($id) {
        return "$id.png";
    }
    
    private static function avaUrl($id) {
        return APP_HTML_AVA_PATH.self::avaFileName($id);
    }
    
    private static function avaFile($id) {
        return APP_FILES_AVA_PATH.self::avaFileName($id);
    }
    
    public static function deleteAvaFromDB($id) {
        $J = new JSON();
        $res = DB::query("UPDATE users_list SET photo='' WHERE id=$id");
        if (!DB::$lastReqState) return $J->error ('Ошибка при обновлении данных в базе <!--'.DB::getError().'-->');
        $J->ava = APP_HTML_DEF_AVA;
        return $J;
    }
    
    
    private static function updateAvaDBrecord($id) {
        $J = new JSON();
        $cts = time();
        $ava = self::avaUrl($id).'?'.$cts;
        $res = DB::query("UPDATE users_list SET photo='$ava' WHERE id=$id");
        if (!DB::$lastReqState) return $J->error ('Ошибка при обновлении данных в базе <!--'.DB::getError().'-->');
        $J->ava = $ava;
        return $J;
    }
    
    
    private static function saveImg($IMG, $id) {
        $path = self::avaFile($id);
        return @imagepng($IMG,$path);
    }
    
    
    /////////////////////////////////////////////////////////////////////
    
    
    public static function checkAva($id) {
        $file = self::avaFile($id);
        if (@is_file($file)) return self::avaUrl($id);
        
        return APP_HTML_DEF_AVA;
    }
    
   
    public static function deleteAva($id) {
        $J = new JSON();
        
        DB::$mysqli->autocommit(FALSE);
        
        $JD = self::deleteAvaFromDB($id);
        if (!$JD->getState()) $J->error($JD->getErrorString());
        else {
            $file = self::avaFile($id);
            if (@is_file($file) ) {
                if (!@unlink($file)) $J->error('Файл не удаляется');
            }
        }
        
        if ($J->getState()) {
            DB::$mysqli->commit();
            $J->ava = $JD->ava;
        }
        else {
            DB::$mysqli->rollback();
        }
        
        DB::$mysqli->autocommit(TRUE);
        return $J;
    }
    
    
    
    
    
    public static function loadAva($id, $field) {
        $J = new JSON();
        
        $filearr = Arr::getValue($_FILES, $field, array());
        if (
                !is_array($filearr)
                || !Arr::getValue($filearr, 'tmp_name', FALSE)
                || (Arr::getValue($filearr, 'tmp_name', FALSE) == 'none')
                || !Arr::getValue($filearr, 'name', FALSE)
            ) {
                return $J->error('Файл не был отправлен (1)');
            }

        $errorcode = Arr::getValue($filearr, 'error', FALSE);
        if ($errorcode) {
            switch ($errorcode) {
                case 1  : return $J->error('Файл слишком большой (F > upload_max_filesize)'); //'The uploaded file exceeds the upload_max_filesize directive in php.ini'
                case 2  : return $J->error('Файл слишком большой (F > MAX_FILE_SIZE)'); //The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form
                case 3  : return $J->error('Файл поврежден при загрузке'); //The uploaded file was only partially uploaded
                case 4  : return $J->error('Файл не был загружен (e4)'); //No file was uploaded
                case 5  : return $J->error('Файл не был сохранен (e5)'); // ???
                case 6  : return $J->error('Файл не был сохранен (e6)'); //Missing a temporary folder
                case 7  : return $J->error('Файл не был сохранен (e7)'); //Failed to write file to disk
                case 8  : return $J->error('Загрузка файла была прервана'); //File upload stopped by extension
                default : return $J->error('Ошибка загрузки файла (eX)'); // ???No error code avaiable
            }
        }

        $tmpFile = Arr::getValue($filearr, 'tmp_name');

        if(!is_file($tmpFile)) {
            return $J->error('Файл не может быть обработан');
        }


        if(!Arr::getValue($filearr, 'size', false)) {
            @unlink($tmpFile);
            return $J->error('Файл пуст (0кБ)');
        }

        $fileName = strtolower(Arr::getValue($filearr, 'name', ''));
        $ext = end(explode(".", $fileName));
        if (!in_array($ext, self::$allowedExtensions) ) {
            unlink($tmpFile);
            return $J->error("Недопустимый формат изображения .$ext");
        }

        $IMG = false;
        $type = exif_imagetype($tmpFile);
	if ($type) $type = image_type_to_mime_type($type);
        switch ($type) {
            case 'image/jpeg':	$IMG = imagecreatefromjpeg($tmpFile);	break;
            case 'image/png':   $IMG = imagecreatefrompng($tmpFile); 	break;
            case 'image/gif':	$IMG = imagecreatefromgif($tmpFile);	break;
            default: {
                unlink($tmpFile);
                return $J->error('Файл не является изображением');
            }
        }

        if (!$IMG) {
            unlink($tmpFile);
            return $J->error('Файл недоступен (ошибка чтения)');
        }

        
        DB::$mysqli->autocommit(FALSE);
        $JD = self::updateAvaDBrecord($id);
        
        if ($JD->getState()) {
            list($w,$h) = @getimagesize($tmpFile);


            $rate = max(array($w,$h))/self::$max_img_dim;
            if ($rate > 1) {
                $nw = $w/$rate;
                $nh = $h/$rate;
                $NEW = imagecreatetruecolor((int)$nw,(int)$nh);
                imagecopyresampled($NEW,$IMG,0,0,0,0,$nw,$nh,$w,$h);
                $res = self::saveImg($NEW, $id);
                imagedestroy($NEW);
            }
            else {
                $res = self::saveImg($IMG, $id);
            }
            imagedestroy($IMG);
            unlink($tmpFile);

            if (!$res) $J->error('Файл не сохранен (ошибка записи)');
        }
        else $J->error($JD->getErrorString());
        
        if ($J->getState()) {
            DB::$mysqli->commit();
            $J->ava = $JD->ava;
        }
        else {
            DB::$mysqli->rollback();
        }
        
        DB::$mysqli->autocommit(TRUE);
        return $J;
    }
}
?>